
#include "diskstream.h"
#include "memory/heap/kheap.h"
#include "config.h"

struct disk_stream* disk_stream_new(const int disk_id)
{
    struct disk* disk = disk_get(disk_id); 
    if (!disk) {
        return 0; 
    }

    struct disk_stream* stream = (struct disk_stream*)kzalloc(sizeof(struct disk_stream)); 
    stream->pos = 0; 
    stream->disk = disk; 

    return stream; 
}

const int disk_stream_seek(struct disk_stream* stream, const int pos)
{
    stream->pos = pos; 
    return 0; 
}

const int disk_stream_read(struct disk_stream* stream, void* out, const int total)
{
    const int sector = stream->pos / TESTOS_SECTOR_SIZE; 
    const int offset = stream->pos % TESTOS_SECTOR_SIZE; 

    char buf[TESTOS_SECTOR_SIZE]; 
    int res = disk_read_block(stream->disk, sector, 1, buf); 
    if (res < 0) {
        goto out; 
    }

    const int total_to_read = total > TESTOS_SECTOR_SIZE ? TESTOS_SECTOR_SIZE : total; 
    char* cout = (char*)out; 
    int i; 

    for (i = 0; i < total_to_read; i++) {
        *cout = buf[offset + i]; 
        cout++; 
    }

    stream->pos += total_to_read; 
    if (total > TESTOS_SECTOR_SIZE) {
        res = disk_stream_read(stream, (void*)cout, total - TESTOS_SECTOR_SIZE); 
        if (res < 0) {
            goto out;
        }
    }

out:
    return res; 
}

void disk_stream_close(struct disk_stream* stream)
{
    kfree(stream); 
}
